package com.liulishuo.okdownload;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.liulishuo.okdownload.core.LogUtillib;
import com.liulishuo.okdownload.core.TextUtils;
import com.liulishuo.okdownload.core.breakpoint.BlockInfo;
import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo;
import com.liulishuo.okdownload.core.cause.EndCause;
import com.liulishuo.okdownload.core.listener.DownloadListener4WithSpeed;
import com.liulishuo.okdownload.core.listener.assist.Listener4SpeedAssistExtend;
import com.liulishuo.okdownload.sample.utils.DemoUtil;
import com.liulishuo.okdownload.sample.utils.LogUtil;
import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.app.Context;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class ExampleOhosTest {

    @Test
    public void downloadTask() {
        Context context = AbilityDelegatorRegistry.getAbilityDelegator().getAppContext();
        final String filename = "single-test-" + System.currentTimeMillis() + ".apk";
        final String url = "https://cdn.llscdn.com/yy/files/xs8qmxn8-lls-LLS-5.8-800-20171207-111607.apk";
        final File parentFile = DemoUtil.getParentFile(context);
        DownloadTask task = new DownloadTask.Builder(url, parentFile)
                .setFilename(filename)
                // the minimal interval millisecond for callback progress
                .setMinIntervalMillisCallbackProcess(16)
                // ignore the same task has already completed in the past.
                .setAutoCallbackToUIThread(true)
                .setPassIfAlreadyCompleted(true)
                .build();

        task.enqueue(new DownloadListener4WithSpeed() {

            @Override
            public void taskStart(DownloadTask task) {
                LogUtil.info("zzhs", "startTask taskStart  " + task);

            }

            @Override
            public void infoReady(DownloadTask task, BreakpointInfo info, boolean fromBreakpoint, Listener4SpeedAssistExtend.Listener4SpeedModel model) {
            }

            @Override
            public void progressBlock(@NonNull DownloadTask task, int blockIndex, long currentBlockOffset, @NonNull SpeedCalculator blockSpeed) {
                LogUtil.info("zzhs", "progressBlock" + task.getInfo());
            }

            @Override
            public void connectStart(DownloadTask task, int blockIndex, Map<String, List<String>> requestHeaders) {
                final String status = "Connect Start " + blockIndex;

            }

            @Override
            public void connectEnd(DownloadTask task, int blockIndex, int responseCode, Map<String, List<String>> responseHeaders) {
                final String status = "Connect End " + blockIndex + "---" + responseCode + "---" + task.getFilename();

            }

            @Override
            public void progress(DownloadTask task, long currentOffset, SpeedCalculator taskSpeed) {

            }

            @Override
            public void blockEnd(DownloadTask task, int blockIndex, BlockInfo info, SpeedCalculator blockSpeed) {
            }

            @Override
            public void taskEnd(DownloadTask task, EndCause cause, @Nullable Exception realCause, SpeedCalculator taskSpeed) {
                final String realMd5 = getFileSHA256(task.getFile());
                if (cause == EndCause.COMPLETED) {
                    LogUtillib.e("zzhs_00700_", "file download success!!!!");
                    Assert.assertTrue(!TextUtils.isEmpty(realMd5) && "1fec0ea40673b1dd6a2a751686d5e0657786504aeebbc42a95b4b14467c845e7".endsWith(realMd5.toLowerCase(Locale.ROOT)));
                }
            }
        });

        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 计算文件 SHA256
     *
     * @param file 文件
     * @return 返回文件的SHA256字符串，如果计算过程中任务的状态变为取消或暂停，返回null， 如果有其他异常，返回空字符串
     */
    private static String getFileSHA256(File file) {
        try (InputStream stream = Files.newInputStream(file.toPath(), StandardOpenOption.READ)) {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] buf = new byte[8192];
            int len;
            while ((len = stream.read(buf)) > 0) {
                digest.update(buf, 0, len);
            }
            return toHexString(digest.digest());
        } catch (IOException | NoSuchAlgorithmException e) {
            LogUtil.error("main", e.getMessage());
            return null;
        }
    }

    private static final char[] HEX_CODE = "0123456789ABCDEF".toCharArray();

    private static String toHexString(byte[] data) {
        StringBuilder string = new StringBuilder(data.length * 2);
        for (byte byt : data) {
            string.append(HEX_CODE[(byt >> 4) & 0xF]);
            string.append(HEX_CODE[(byt & 0xF)]);
        }
        return string.toString();
    }
}